/*
 * Copyright (c) 2008, 2016, OneAPM and/or its affiliates. All rights reserved.
 */
package me.yufan.chess.config;

import me.yufan.chess.operation.ErrorHandler;
import me.yufan.chess.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

/**
 * Title: Options
 * Description: Handles all user options.
 *
 * @author Yufan
 * @version 1.0.0
 * @since 2016-01-26 19:40
 */
public final class Options {

    private static final Logger LOGGER = LoggerFactory.getLogger(Options.class);

    /**
     * Whether to use XDG directories.
     */
    public static final boolean USE_XDG = checkXDGFlag();

    /**
     * Font file name.
     */
    public static final String FONT_NAME = "DroidSansFallback.ttf";

    /**
     * The cache directory.
     */
    private static final File CACHE_DIR = getXDGBaseDir("XDG_CACHE_HOME", ".cache");

    /**
     * Directory where natives are unpacked.
     */
    public static final File NATIVE_DIR = new File(CACHE_DIR, "Natives/");

    /**
     * The config directory.
     */
    private static final File CONFIG_DIR = getXDGBaseDir("XDG_CONFIG_HOME", ".config");

    /**
     * File for logging errors.
     */
    public static final File LOG_FILE = new File(CONFIG_DIR, ".program.log");

    private Options() {
        // This class should not be instantiated.
    }

    /**
     * Returns whether the XDG flag in the manifest (if any) is set to "true".
     *
     * @return true if XDG directories are enabled, false otherwise
     */
    private static boolean checkXDGFlag() {
        JarFile jarFile = Utils.getJarFile();
        if (jarFile == null) {
            return false;
        }
        try {
            Manifest manifest = jarFile.getManifest();
            if (manifest == null) {
                return false;
            }
            Attributes attributes = manifest.getMainAttributes();
            String value = attributes.getValue("Use-XDG");
            return "true".equalsIgnoreCase(value);
        } catch (IOException e) {
            LOGGER.debug("", e);
            return false;
        }
    }

    /**
     * Returns the directory based on the XDG base directory specification for
     * Unix-like operating systems, only if the "XDG" flag is enabled.
     *
     * @param env      the environment variable to check (XDG_*_*)
     * @param fallback the fallback directory relative to ~home
     * @return the XDG base directory, or the working directory if unavailable
     */
    private static File getXDGBaseDir(String env, String fallback) {
        if (!USE_XDG) {
            return new File("./");
        }
        String os = System.getProperty("os.name").toLowerCase();
        if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
            String rootPath = System.getenv(env);
            if (rootPath == null) {
                String home = System.getProperty("user.home");
                if (home == null) {
                    return new File("./");
                }
                rootPath = String.format("%s/%s", home, fallback);
            }
            File dir = new File(rootPath, "chess");
            if (!dir.isDirectory() && !dir.mkdir())
                ErrorHandler.error(
                    String.format("Failed to create configuration folder at '%s/opsu'.", rootPath),
                    null);
            return dir;
        } else
            return new File("./");
    }
}
